package model.strategys.resolucao;

import model.cubos.Adesivo;
import model.cubos.Cor;
import model.cubos.CuboMagico3x3x3;
import model.rotations.Rotations;

public class ResolveBase extends Estrategia{

	public ResolveBase(Rotations rotacao) {
		super(rotacao);
	}

	public void resolveBase(CuboMagico3x3x3 cubo) {

		Adesivo[][][] matriz = cubo.getCubo();
		
		boolean isFinished = false;

		if (matriz[5][0][0].getKey() == 45 && matriz[5][0][2].getKey() == 47
				&& matriz[5][2][0].getKey() == 51
				&& matriz[5][2][2].getKey() == 53)
			isFinished = true;

		while (!isFinished) {

			if (matriz[0][0][0].isCor(Cor.BRANCO) | // (matriz[0][0][0].getKey() >= 45 && matriz[0][0][0].getKey() <= 53) |
					(matriz[1][0][0].isCor(Cor.BRANCO)) | 
					(matriz[2][0][0].isCor(Cor.BRANCO)) |
					(matriz[3][0][0].isCor(Cor.BRANCO))) {

				etapa1(cubo, matriz);

			} else if (matriz[0][0][2].isCor(Cor.BRANCO) |
					(matriz[1][0][2].isCor(Cor.BRANCO)) |
					(matriz[2][0][2].isCor(Cor.BRANCO)) |
					(matriz[3][0][2].isCor(Cor.BRANCO))) {

				etapa2(cubo, matriz);

			}

			else if (matriz[4][0][0].isCor(Cor.BRANCO) |
					matriz[4][0][2].isCor(Cor.BRANCO) |
					matriz[4][2][0].isCor(Cor.BRANCO) |
					matriz[4][2][2].isCor(Cor.BRANCO)) {

				etapa3(cubo, matriz);
			} else if (matriz[0][2][2].isCor(Cor.BRANCO) |
					matriz[1][2][2].isCor(Cor.BRANCO) |
					matriz[2][2][2].isCor(Cor.BRANCO) |
					matriz[3][2][2].isCor(Cor.BRANCO)) {

				etapa4(cubo, matriz);
			}

			else if (matriz[0][2][0].isCor(Cor.BRANCO) |
					matriz[1][2][0].isCor(Cor.BRANCO) |
					matriz[2][2][0].isCor(Cor.BRANCO) |
					matriz[3][2][0].isCor(Cor.BRANCO)) {
				etapa5(cubo, matriz);
			} else {
				etapa6(cubo, matriz);

			}
			// fim da etapa 6
			if (matriz[5][0][0].isCor(Cor.BRANCO) &&
					matriz[5][0][2].isCor(Cor.BRANCO) &&
					matriz[5][2][0].isCor(Cor.BRANCO) &&
					matriz[5][2][2].isCor(Cor.BRANCO))
				isFinished = true;
		}
	}

	private void etapa6(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {
	
		for (int i = 0; i < 4; i++) {
	
			if (matriz[0][2][0].isCor(Cor.AZUL)) {
				if (!matriz[0][1][1].isCor(Cor.AZUL)) {
					etapa6Rotacoes(cubo);
				}
			} else if (matriz[0][2][0].isCor(Cor.VERMELHO)) {
				if (!matriz[0][1][1].isCor(Cor.VERMELHO)) {
					etapa6Rotacoes(cubo);
				}
			} else if (matriz[0][2][0].isCor(Cor.VERDE)) {
				if (!matriz[0][1][1].isCor(Cor.VERDE)) {
					etapa6Rotacoes(cubo);
				}
			} else if (matriz[0][2][0].isCor(Cor.LARANJA)) {
				if (!matriz[0][1][1].isCor(Cor.LARANJA)) {
					etapa6Rotacoes(cubo);
				}
			}
			rotacao.girarEixoYSentidoHorario(cubo);
		}
	}

	private void etapa6Rotacoes(CuboMagico3x3x3 cubo) {
		rotacao.girarEsquerdaSentidoAntiHorario(cubo);
		rotacao.girarCimaSentidoAntiHorario(cubo);
		rotacao.girarEsquerdaSentidoHorario(cubo);
	}

	private void etapa5(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {

		while (!matriz[0][2][0].isCor(Cor.BRANCO)) {
			rotacao.girarEixoYSentidoHorario(cubo);
		}

		rotacao.girarEsquerdaSentidoAntiHorario(cubo);
		rotacao.girarCimaSentidoHorario(cubo);
		rotacao.girarEsquerdaSentidoHorario(cubo);
	}

	private void etapa4(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {

		while (!matriz[0][2][2].isCor(Cor.BRANCO)) {
			rotacao.girarEixoYSentidoHorario(cubo);
		}

		rotacao.girarDireitaSentidoHorario(cubo);
		rotacao.girarCimaSentidoAntiHorario(cubo);
		rotacao.girarDireitaSentidoAntiHorario(cubo);
	}

	private void etapa3(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {

		while (!matriz[4][2][2].isCor(Cor.BRANCO)) {
			rotacao.girarCimaSentidoHorario(cubo);
		}

		if (matriz[5][0][2].isCor(Cor.BRANCO)) {

			while (matriz[5][0][2].isCor(Cor.BRANCO)) {
				rotacao.girarCamadaMeioHorizontalSentidoHorario(cubo);
				rotacao.girarBaseSentidoHorario(cubo);
			}
		}

		rotacao.girarDireitaSentidoHorario(cubo);
		rotacao.girarCimaSentidoHorario(cubo);
		rotacao.girarCimaSentidoHorario(cubo);
		rotacao.girarDireitaSentidoAntiHorario(cubo);
	}

	private void etapa2(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {

		while (!matriz[3][0][2].isCor(Cor.BRANCO)) {
			rotacao.girarCimaSentidoHorario(cubo);
		}

		if (matriz[0][0][0].isCor(Cor.AZUL)) {
			etapa2Rotacoes(cubo, matriz, Cor.AZUL);
		} else if (matriz[0][0][0].isCor(Cor.VERMELHO)) {
			etapa2Rotacoes(cubo, matriz, Cor.VERMELHO);
		}

		else if (matriz[0][0][0].isCor(Cor.VERDE)) {
			etapa2Rotacoes(cubo, matriz, Cor.VERDE);
		}

		else if (matriz[0][0][0].isCor(Cor.LARANJA)) {
			etapa2Rotacoes(cubo, matriz, Cor.LARANJA);
		}
	}

	private void etapa2Rotacoes(CuboMagico3x3x3 cubo, Adesivo[][][] matriz,
			model.cubos.Cor corAtual) {

		while (!matriz[0][1][1].isCor(corAtual)) {
			rotacao.girarCamadaMeioHorizontalSentidoHorario(cubo);
			rotacao.girarBaseSentidoHorario(cubo);
		}

		rotacao.girarEsquerdaSentidoAntiHorario(cubo);
		rotacao.girarCimaSentidoAntiHorario(cubo);
		rotacao.girarEsquerdaSentidoHorario(cubo);
	}

	private void etapa1(CuboMagico3x3x3 cubo, Adesivo[][][] matriz) {

		while (!matriz[1][0][0].isCor(Cor.BRANCO)) {
			rotacao.girarCimaSentidoHorario(cubo);
		}

		if (matriz[0][0][2].isCor(Cor.AZUL)) {
			etapa1Rotacoes(cubo, matriz, Cor.AZUL);
		} else if (matriz[0][0][2].isCor(Cor.VERMELHO)) {

			etapa1Rotacoes(cubo, matriz, Cor.VERMELHO);
		}

		else if (matriz[0][0][2].isCor(Cor.VERDE)) {

			etapa1Rotacoes(cubo, matriz, Cor.VERDE);
		}

		else if (matriz[0][0][2].isCor(Cor.LARANJA)) {
			etapa1Rotacoes(cubo, matriz, Cor.LARANJA);
		}
	}

	private void etapa1Rotacoes(CuboMagico3x3x3 cubo, Adesivo[][][] matriz,
			model.cubos.Cor corAtual) {

		while (!matriz[0][1][1].isCor(corAtual)) {
			rotacao.girarCamadaMeioHorizontalSentidoHorario(cubo);
			rotacao.girarBaseSentidoHorario(cubo);
		}

		rotacao.girarDireitaSentidoHorario(cubo);
		rotacao.girarCimaSentidoHorario(cubo);
		rotacao.girarDireitaSentidoAntiHorario(cubo);
	}
}
